
//1. 测试readv和writev
// #include <iostream>
// #include <netdb.h>
// #include <sys/types.h>
// #include <sys/stat.h>
// #include <fcntl.h>

// int main()
// {
//     char buffer1[10] = {0};
//     char buffer2[10] = {0};
//     char buffer3[50] = {0};
//     struct iovec vec[3];
//     vec[0].iov_base = buffer1;
//     vec[0].iov_len = 10;

//     vec[1].iov_base = buffer2;
//     vec[1].iov_len = 10;
    
//     vec[2].iov_base = buffer3;
//     vec[2].iov_len = 50;

//     int fd = open("./test.txt",O_RDWR);
//     readv(fd,vec,3);
    
//     std::cout << "buffer1: " << buffer1 << std::endl;
//     std::cout << "buffer2: " << buffer2 << std::endl;
//     std::cout << "buffer3: " << buffer3 << std::endl;

//     char write_buffer1[] = "你是我的眼";
//     char write_buffer2[] = "带我领略四季的变换";

//     struct iovec vec2[2];
//     vec2[0].iov_base = write_buffer1;
//     vec2[0].iov_len = sizeof(write_buffer1);

//     vec2[1].iov_base = write_buffer2;
//     vec2[1].iov_len = sizeof(write_buffer2);
//     writev(fd,vec2,2);
//     return 0;
// }


//2. sendfile测试
//  #include <arpa/inet.h>
//  #include <sys/socket.h>
//  #include <netinet/in.h>
//  #include <unistd.h>
//  #include <string.h>
// #include <sys/types.h>
// #include <sys/stat.h>
// #include <fcntl.h>
// #include <sys/sendfile.h>
// #include <iostream>

// int main()
// {
//     int fd = socket(AF_INET,SOCK_STREAM,0);
//     int val = 1;
//     setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val));

//     struct sockaddr_in ipv4;
//     memset(&ipv4,0,sizeof(ipv4));
//     ipv4.sin_family = AF_INET;
//     ipv4.sin_port = htons(9090);
//     ipv4.sin_addr.s_addr = inet_addr("0.0.0.0");
//     socklen_t len = sizeof(ipv4);
//     bind(fd,(const sockaddr *)&ipv4,len);

//     listen(fd,2);

//     struct sockaddr_in client;
//     len = sizeof(client);
//     //sleep(5);
//     int n = accept(fd,(sockaddr *)&client,&len);
//     if(n < 0)
//     {
//         std::cout << "accept失败！" << std::endl;
//     }
//     else
//     {
//         int fd = open("./test.txt",O_RDWR);
//         struct stat file_buffer;
//         fstat(fd,&file_buffer);
//         sendfile(n,fd,nullptr,file_buffer.st_size);
//     }
//     return 0;
// }


//3. 回射服务器demo-利用splice实现
// #include <arpa/inet.h>
// #include <sys/socket.h>
// #include <netinet/in.h>
// #include <unistd.h>
// #include <string.h>
// #include <sys/types.h>
// #include <sys/stat.h>
// #include <fcntl.h>
// #include <sys/sendfile.h>
// #include <iostream>

// int main()
// {
//     int fd = socket(AF_INET,SOCK_STREAM,0);
//     int val = 1;
//     setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val));

//     struct sockaddr_in ipv4;
//     memset(&ipv4,0,sizeof(ipv4));
//     ipv4.sin_family = AF_INET;
//     ipv4.sin_port = htons(9090);
//     ipv4.sin_addr.s_addr = inet_addr("0.0.0.0");
//     socklen_t len = sizeof(ipv4);
//     bind(fd,(const sockaddr *)&ipv4,len);

//     listen(fd,2);

//     struct sockaddr_in client;
//     len = sizeof(client);
//     //sleep(5);
//     int n = accept(fd,(sockaddr *)&client,&len);
//     if(n < 0)
//     {
//         std::cout << "accept失败！" << std::endl;
//     }
//     else
//     {
//         int pipefd[2];
//         pipe(pipefd);
//         splice(n,nullptr,pipefd[1],nullptr,32768,SPLICE_F_MOVE | SPLICE_F_MOVE);
//         splice(pipefd[0],nullptr,n,nullptr,32768,SPLICE_F_MOVE | SPLICE_F_MOVE);
//     }
//     close(n);
//     close(fd);
//     return 0;
// }


//4. 测试tee函数
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>

int main()
{
    umask(0);
    int filefd = open("./test222.txt", O_CREAT | O_WRONLY, 0666);
    if(filefd == -1)
    {
        std::cout << "打开文件失败！" << std::endl;
        return -1;
    }
    int pipefd1[2];
    pipe(pipefd1);
    int pipefd2[2];
    pipe(pipefd2);

    splice(0,nullptr,pipefd1[1],nullptr,32768,SPLICE_F_MOVE | SPLICE_F_MORE);
    tee(pipefd1[0],pipefd2[1],32768,SPLICE_F_NONBLOCK);
    ssize_t n = splice(pipefd2[0],nullptr,filefd,nullptr,32768,SPLICE_F_MOVE | SPLICE_F_MORE);
    std::cout << "向文件了写入了" << n << "个字节的数据" << std::endl;
    splice(pipefd1[0],nullptr,1,nullptr,32768,SPLICE_F_MOVE | SPLICE_F_MORE);
    
    close(filefd);
    close(pipefd1[0]);
    close(pipefd1[1]);
    close(pipefd2[0]);
    close(pipefd2[1]);


    return 0;
}